home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Sample Code / Snippets / Toolbox / Password / Source / Password.c next >
Encoding:
Text File  |  1996-09-17  |  8.2 KB  |  289 lines  |  [TEXT/CWIE]

  1. //
  2. //    Password
  3. //     Sample of three different ways to implement a password dialog
  4. //
  5. //    Tim Dierks, UK Mac DTS
  6. //    August, 1991
  7. //
  8. //        9/13/96 PG stopped returning addresses of local variables -- duh!
  9. //
  10. //    This file contains all the interesting password stuff:
  11. //   Sample.c is just the application shell, derived from CSample
  12.  
  13. #include <Types.h>
  14. #include <Memory.h>
  15. #include <Resources.h>
  16. #include <OSUtils.h>
  17. #include <Quickdraw.h>
  18. #include <Fonts.h>
  19. #include <Events.h>
  20. #include <OSEvents.h>
  21. #include <Windows.h>
  22. #include <Menus.h>
  23. #include <Dialogs.h>
  24. #include <TextEdit.h>
  25.  
  26. #include "Sample.h"
  27. #include "Password.h"
  28.  
  29. void DisplayPassword (ConstStr255Param password)
  30. {    DialogPtr    dlog;
  31.     short        item;
  32.     //short        rDisplayPasswordDialog;
  33.     
  34.     dlog = GetNewDialog(rDisplayPasswordDialog,0L,(WindowPtr) -1L);
  35.     
  36.     ParamText((ConstStr255Param)password,0L,0L,0L);
  37.     
  38.     do
  39.     {    ModalDialog(0L,&item);
  40.     } while (item != 1);            // Until the OK button gets hit
  41.     
  42.     DisposeDialog(dlog);
  43. }
  44.  
  45. void TwoItemDialog (StringPtr password)
  46. {
  47.     DialogPtr        dlog;
  48.     Handle            itemH;
  49.     ControlHandle    chkBox;
  50.     short            item,itemType,chkVal;
  51.     Rect            box;
  52.     Point            size;
  53.  
  54.     static ModalFilterUPP twoItemFilterUPP;
  55.     
  56.     /* set up a UPP for the dialog filter */
  57.  
  58.     if (!twoItemFilterUPP)
  59.         twoItemFilterUPP = NewModalFilterProc(TwoItemFilter);
  60.     
  61.     dlog = GetNewDialog(rTwoItemDialog,0L,(WindowPtr) -1L);
  62.     
  63.     if (dlog)
  64.     {
  65.         do
  66.         {    ModalDialog(twoItemFilterUPP,&item);
  67.             if (item == 4)                                            // Hide/show checkbox
  68.             {    GetDialogItem(dlog,4,&itemType,(Handle*)&chkBox,&box);    // Get check value
  69.                 chkVal = !GetControlValue(chkBox);
  70.                 SetControlValue(chkBox,chkVal);                            // Invert it
  71.                 size.v = dlog->portRect.bottom - dlog->portRect.top;
  72.                 size.h = dlog->portRect.right - dlog->portRect.left;
  73.                 if (chkVal)
  74.                     size.v += 35;
  75.                 else
  76.                     size.v -= 35;
  77.                 
  78.                 SizeWindow(dlog,size.h,size.v,true);        // Resize window
  79.             }
  80.         } while (item != 1);            // Until the OK button is hit
  81.     
  82.         GetDialogItem(dlog,3,&itemType,&itemH,&box);        // Get text from hidden dialog item
  83.         GetDialogItemText(itemH, password);
  84.         
  85.         DisposeDialog(dlog);
  86.     }
  87. }
  88.  
  89. pascal Boolean
  90. TwoItemFilter(DialogPtr dlog,EventRecord *event,short *itemHit)
  91. {    DialogPtr    evtDlog;
  92.     short        selStart,selEnd;
  93.     
  94.     if (event->what == keyDown || event->what == autoKey)
  95.     {    switch (event->message & charCodeMask)
  96.         {    case '\n':            // Return  (hitting return or enter is the same as hitting the OK button)
  97.             case '\003':        // Enter
  98.                 *itemHit = 1;        // OK Button
  99.                 return true;        // We handled the event
  100.             case '\t':            // Tab
  101.                 event->what = nullEvent;    // Do nothing (don't let the user tab to the hidden field)
  102.                 return false;
  103.             case '\034':        // Left arrow  (Keys that just change the selection)
  104.             case '\035':        // Right arrow
  105.             case '\036':        // Up arrow
  106.             case '\037':        // Down arrow
  107.                 return false;            // Let ModalDialog handle them
  108.             default:
  109.                 selStart = (**((DialogPeek)dlog)->textH).selStart;        // Get the selection in the visible item
  110.                 selEnd = (**((DialogPeek)dlog)->textH).selEnd;
  111.                 SelectDialogItemText(dlog,3,selStart,selEnd);                // Select text in invisible item
  112.                 DialogSelect(event,&evtDlog,itemHit);            // Input key
  113.                 SelectDialogItemText(dlog,2,selStart,selEnd);                // Select same area in visible item
  114.                 if ((event->message & charCodeMask) != '\010')    // If it's not a backspace (backspace is the only key that can affect both the text and the selection- thus we need to process it in both fields, but not change it for the hidden field.
  115.                     event->message = '•';                        // Replace with character to use
  116.                 DialogSelect(event,&evtDlog,itemHit);            // Put in fake character
  117.                 return true;
  118.         }
  119.     }
  120.     
  121.     return false;            // For all non-keyDown events
  122. }
  123.  
  124. void DifferentFontDialog (StringPtr password)
  125. {
  126.     DialogPtr        dlog;
  127.     Handle            itemH;
  128.     short            item,itemType,font;
  129.     Rect            box;
  130.     UserItemUPP     chicagoTextItemUPP;
  131.     //short             rDifferentFontDialog;
  132.     
  133.     /* create the UPP for our ChicagoTextItem userItem */
  134.     chicagoTextItemUPP = NewUserItemProc(ChicagoTextItem);
  135.     
  136.     GetFNum("\p.Pwd",&font);        // Get the font number for our password font (it begins with a period, so AppendResMenu won't add it)
  137.     SetDialogFont(font);                // Use this font for static and edit text items in further dialogs
  138.     
  139.     dlog = GetNewDialog(rDifferentFontDialog,0L,(WindowPtr) -1L);
  140.     
  141.     GetDialogItem(dlog,3,&itemType,&itemH,&box);            // Because SetDialogFont affects static items, too, we've got to use user items to draw our prompts
  142.     SetDialogItem(dlog,3,itemType,(Handle)chicagoTextItemUPP,&box);
  143.     GetDialogItem(dlog,4,&itemType,&itemH,&box);
  144.     SetDialogItem(dlog,4,itemType,(Handle)chicagoTextItemUPP,&box);
  145.     
  146.     do
  147.     {    ModalDialog(0L,&item);
  148.     } while (item != 1);            // Until the OK button is hit
  149.     
  150.     GetDialogItem(dlog,2,&itemType,&itemH,&box);        // Get text from TE item
  151.     GetDialogItemText(itemH, password);
  152.     
  153.     DisposeDialog(dlog);
  154.     
  155.     SetDialogFont(0);        // Set the dialog font back to the System font
  156.     
  157.     DisposeRoutineDescriptor(chicagoTextItemUPP);
  158. }
  159.  
  160. pascal void
  161. ChicagoTextItem(WindowPtr wind,short item)
  162. {    short        fontStore,sizeStore;
  163.     Handle        itemH;
  164.     short        itemType;
  165.     Rect        box;
  166.     char        *text;
  167.     
  168.     SetPort(wind);
  169.     
  170.     fontStore = wind->txFont;    // Remember the current font & size
  171.     sizeStore = wind->txSize;
  172.     
  173.     TextFont(0);        // Set to default System font & size
  174.     TextSize(0);
  175.     
  176.     GetDialogItem(wind,item,&itemType,&itemH,&box);
  177.     
  178.     if (item == 3)            // These strings would probably be in a resource or somesuch in an actual program.
  179.         (ConstStr255Param) text = "\pPlease enter your password:";
  180.     if (item == 4)
  181.         (ConstStr255Param) text = "\pSpecial Font Password Dialog";
  182.     
  183.     TETextBox(text+1,*text,&box,teJustLeft);    // Draw the prompt
  184.     
  185.     TextFont(fontStore);        // Restore the font & size
  186.     TextSize(sizeStore);
  187. }
  188.  
  189. void InternalBufferDialog (StringPtr password)
  190. {
  191.     DialogPtr        dlog;
  192.     short            item;
  193.     ModalFilterUPP  internalBufferFilterUPP;
  194.     //short            rInternalBufferDialog;
  195.     
  196.     /* create the UPP for the InternalBufferFilter */
  197.     internalBufferFilterUPP = NewModalFilterProc(InternalBufferFilter);
  198.     
  199.     dlog = GetNewDialog(rInternalBufferDialog,0L,(WindowPtr) -1L);
  200.     
  201.     *password = '\0';                    // Zero out the buffered password
  202.     SetWRefCon(dlog,(long)password);    // Stash the buffer's address
  203.     
  204.     do
  205.     {    ModalDialog(internalBufferFilterUPP,&item);
  206.     } while (item != 1);            // Until the OK button is hit
  207.     
  208.     DisposeDialog(dlog);
  209.     
  210.     DisposeRoutineDescriptor(internalBufferFilterUPP);
  211. }
  212.  
  213. pascal Boolean
  214. InternalBufferFilter(DialogPtr dlog,EventRecord *event,short *itemHit)
  215. {    char    key;
  216.     short    start,end;
  217.     char    *buffer;
  218.     
  219.     if (event->what != keyDown && event->what != autoKey)
  220.         return false;                // We don't want to deal with them
  221.     
  222.     key = event->message & charCodeMask;
  223.     
  224.     switch (key)
  225.     {    case '\n':            // Return
  226.         case '\003':        // Enter
  227.             *itemHit = 1;        // OK Button
  228.             return true;        // We handled the event
  229.         case '\t':            // Tab
  230.         case '\034':        // Left arrow
  231.         case '\035':        // Right arrow
  232.         case '\036':        // Up arrow
  233.         case '\037':        // Down arrow
  234.             return false;        // Let ModalDialog handle them
  235.         default:            // Everything else falls through to be dealt with
  236.             break;            //    below
  237.     }
  238.     
  239.     start = (**((DialogPeek)dlog)->textH).selStart;    // Get the current selection
  240.     end = (**((DialogPeek)dlog)->textH).selEnd;
  241.     
  242.     buffer = (char*)GetWRefCon(dlog);        // Get the buffer's address
  243.     
  244.     if (start != end)                    // If there's a selection, delete it
  245.         DeleteRange(buffer,start,end);
  246.     
  247.     if (key == '\010')    // Backspace
  248.     {    if (start != 0)
  249.             DeleteRange(buffer,start-1,start);    // Delete the character to the left
  250.     }
  251.     else
  252.     {    InsertChar(buffer,start,key);        // Insert the real key into the buffer
  253.         event->message = '*';                // Character to use in field
  254.     }
  255.     
  256.     return false;         // Let ModalDialog insert the fake char
  257. }
  258.  
  259. void
  260. DeleteRange(char *buffer,short start,short end)
  261. {    register char    *src,*dest,*last;
  262.     
  263.     last = buffer + *buffer;
  264.     
  265.     src = buffer + end + 1;
  266.     dest = buffer + start + 1;
  267.     
  268.     while (src <= last)            // Shift character to the left over the removed characters
  269.         *(dest++) = *(src++);
  270.     
  271.     (*buffer) -= (end-start);    // Adjust the buffer's length
  272. }
  273.  
  274. void
  275. InsertChar(char *buffer,short pos,char c)
  276. {    register short    index,len;
  277.     
  278.     len = *buffer;
  279.     
  280.     if (len == 0xFF)        // if the string is full, return
  281.         return;
  282.     
  283.     for (index = len;index > pos;index--)    // Shift characters to the right to make room
  284.         buffer[index+1] = buffer[index];
  285.     
  286.     buffer[pos+1] = c;        // Fill in the new character
  287.     
  288.     (*buffer)++;            // Add one to the length of the string
  289. }